package cn.chinaunicom.fast.common.utils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.util.StringUtils;

import cn.chinaunicom.fast.common.params.CephProps;
import lombok.extern.slf4j.Slf4j;

/**
 * ceph工具类
 *
 * @author zzp
 */
@Slf4j
public class CephUtils {
    
    private CephUtils() {}
    
    private static CephUtils ceph;

    /**
     * 日志
     */
    private static Logger logger;

    /**
     * ceph客户端连接对象
     */
    private static AmazonS3 s3Client;
    /**
     * 存储桶名称
     */
    private static Bucket bucket;

    /**
     * 配置信息
     */
    private static CephProps props;
    
    /**
     * 获取单例
     * 
     * @param cephProps
     * @return
     * @throws IOException
     */
    public static CephUtils getInstance(CephProps cephProps) {
    	if(Objects.isNull(props) || Objects.isNull(s3Client)) {
    		props = cephProps;
    		init();
    	}
    	// 防止并发
    	if(ceph == null) {
	    	synchronized (CephUtils.class) {
	    		ceph = Objects.isNull(ceph) ? new CephUtils() : ceph;	
			}
    	}
    	return ceph;
    }

    /**
     * 对象初始化
     */
    public static void init() {
        bucket = new Bucket();
		logger = LoggerFactory.getLogger(CephUtils.class);
		
		log.info("查看参数是否获取到 : {}", props.toString());
		bucket.setName(props.getBucketName());

        BasicAWSCredentials credentials = new BasicAWSCredentials(props.getAccessKey(), props.getSecretKey());
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setProtocol(Protocol.HTTP);
        s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withClientConfiguration(clientConfiguration)
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(props.getEndPoint(), Regions.CN_NORTH_1.getName()))
                .build();
    }

    /**
     * ceph 文件上传
     *
     * @param file
     * @return
     */
    public String uploads(MultipartFile file, String fname) throws IOException {
        // 新建对象并上传
        ByteArrayInputStream input = new ByteArrayInputStream(file.getBytes());
        ObjectMetadata objMeta = new ObjectMetadata();
        objMeta.setContentLength(input.available());
        objMeta.setCacheControl("no-cache");
        objMeta.setContentType(getContentType(fname.substring(fname.lastIndexOf("."))));
        objMeta.setContentDisposition("inline;filename=" + fname);
        objMeta.setContentEncoding("utf-8");
        
        // 上传文件
        String nowDate = DateUtil.dateForm(new Date());
        String cephName = nowDate + "/" + fname;
        
        PutObjectResult putRst = s3Client.putObject(props.getBucketName(), cephName, input, objMeta);
        // 修改一个对象的 ACL
        s3Client.setObjectAcl(props.getBucketName(), cephName, CannedAccessControlList.PublicRead);
        if (logger.isDebugEnabled()) {
            logger.debug("url:" + s3Client.getUrl(bucket.getName(), file.getName()));
            logger.debug(putRst.getETag() + "     " + putRst.getContentMd5());
        }
        return props.getDownLoadUrl() + cephName;
    }
    
    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FileNameExtension 文件后缀
     * @return String
     */
    public String getContentType(String FileNameExtension) {
        if ("bmp".equalsIgnoreCase(FileNameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FileNameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FileNameExtension) ||
                "jpg".equalsIgnoreCase(FileNameExtension) ||
                "png".equalsIgnoreCase(FileNameExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(FileNameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FileNameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FileNameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FileNameExtension) ||
                "ppt".equalsIgnoreCase(FileNameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FileNameExtension) ||
                "doc".equalsIgnoreCase(FileNameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FileNameExtension)) {
            return "text/xml";
        }
        return "image/jpeg";
    }

    /**
     * 获取url
     *
     * @param putRst
     * @param fileName
     * @return
     */
    @SuppressWarnings("unused")
	@Deprecated
    private String getUrl(PutObjectResult putRst, String fileName) {
        if (putRst != null) {
            // 生成对象的下载 URLs (带签名和不带签名)，java仅支持带签名的
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket.getName(), fileName);
            String fileUrl = s3Client.generatePresignedUrl(request).getFile();
            // 判断是为图片, 生成本系统能够访问的url
            if (!StringUtils.isNullOrEmpty(props.getDownLoadUrl())) {
                fileUrl = props.getDownLoadUrl() + fileUrl;
            }
            return fileUrl;
        } else {
            return null;
        }
    }

    /**
     * 下载文件对象
     *
     * @param cephFileName
     * @return
     */
    public S3Object getFileObject(String cephFileName) {
        try {
            GetObjectRequest gor = new GetObjectRequest(bucket.getName(), cephFileName);
            return s3Client.getObject(gor);
        } catch (AmazonServiceException e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }

}
